import { message } from 'antd'
import * as R from 'ramda'
import { isSuccess } from '@/utils/common'
import {
  queryPost, editOrDeletePost, pageablePost, arrayPost,
  listGet, queryGet,
  editPut, queryPut,
  remove, removeDelete, postRequestParam, postReq,
} from '@/services/common'

const setData = R.compose(
  R.assoc('data', R.__, { loading: false }),
  R.propOr({}, 'data'),
)

/**
 * Created by: 耿德洲
 * Created in: 2019/3/19 10:17
 * description: 这是一个通用的modal层，作用让你不用写modal和services
 * rules: {
 *    1.你必须保证你所增加的方法是common类型的。
 *    2.你必须保证在已经理解这个类的前提下修改或者增加公共方法。
 *    3.里面的方法几乎涵盖了所有的请求方式和方法但个别情况下依然需要你写一个modal层。
 *
 * }
 */

export default {
  namespace: 'common',

  state: {
    data: {
      list: [],
      pagination: {},
      rows: [], // 有的返回的是rows。
    },
    loading: true,
    listData: [],
    fetchUrl: undefined, // 当前分页查询url
  },

  effects: {

    /** **********************          post请求                       ******************************** **/

    *pagePost({ payload, callback }, { put, call }) {
      yield put({
        type: 'save',
        payload: { loading: true }
      })
      const response = yield call(queryPost, payload);
      if (!isSuccess(response)) message.error(response.statusMessage)
      yield put({
        type: 'save',
        payload: setData(response),
      })
      if (callback) callback(response);
    },

    *pageablePost({ payload, callback }, { put, call, select }) {
      const { url } = payload;
      yield put({
        type: 'save',
        payload: { loading: true }
      })
      const fetchUrl = yield select(state => state.common.fetchUrl);
      // 分页查询时清除原有数据，避免数据残留问题
      if (url !== fetchUrl) {
        yield put({ type: 'save', payload: { data: { list: [], pagination: {}, rows: [] }, fetchUrl: url } });
      }
      const response = yield call(pageablePost, payload);
      if (!isSuccess(response) && response.statusMessage) message.error(response.statusMessage)
      yield put({
        type: 'save',
        payload: setData(response),
      })
      if (callback) callback(response);
    },

    *queryPost({ payload, callback }, { put, call }) {
      const response = yield call(queryPost, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },

    *arrayPost({ payload, callback }, { put, call }) {
      const response = yield call(arrayPost, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },

    *editOrDeletePost({ payload, callback }, { put, call }) {
      const response = yield call(editOrDeletePost, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },

    *postRequestParam({ payload, callback }, { put, call }) {
      const response = yield call(postRequestParam, payload);
      if (callback) callback(response);
    },

    *postReq({ payload, callback }, { put, call }) {
      const response = yield call(postReq, payload);
      if (callback) callback(response);
    },

    /** ***********************************    GET请求       **********************************************/

    *queryGet({ payload, callback }, { put, call }) {
      const response = yield call(queryGet, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },

    *listGet({ payload, callback }, { put, call }) {
      yield put({
        type: 'save',
        payload: { loading: true }
      })
      const response = yield call(listGet, payload);
      yield put({
        type: 'save',
        payload: { listData: response, loading: false },
      })
      if (callback) callback(response);
    },

    *listDataGet({ payload, callback }, { put, call }) {
      yield put({
        type: 'save',
        payload: { loading: true },
      })
      const response = yield call(listGet, payload)
      yield put({
        type: 'save',
        payload: { listData: response.data, loading: false },
      })
      if (callback) callback(response)
    },

    *pageGet({ payload, callback }, { put, call }) {
      yield put({
        type: 'save',
        payload: { loading: true },
      })
      const response = yield call(listGet, payload)
      if (!isSuccess(response)) message.error(response.statusMessage)
      yield put({
        type: 'save',
        payload: setData(response),
      })
      if (callback) callback(response)
    },

    *pageGetByCode({ payload, callback }, { put, call, select }) {
      const { url } = payload;
      yield put({
        type: 'save',
        payload: { loading: true }
      })
      const fetchUrl = yield select(state => state.common.fetchUrl);
      // 分页查询时清除原有数据，避免数据残留问题
      if (url !== fetchUrl) {
        yield put({ type: 'save', payload: { data: { list: [], pagination: {}, rows: [] }, fetchUrl: url } });
      }
      const response = yield call(listGet, payload);
      yield put({
        type: 'save',
        payload: response.code && response.code === '500' ? { loading: false } : { data: response, loading: false }
      })
      if (callback) callback(response);
    },

    *queryListGet({ payload, callback }, { put, call }) {
      const response = yield call(listGet, payload);
      if (callback) callback(response);
    },

    *fetchGet({ payload, callback }, { put, call }) {
      const response = yield call(listGet, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },

    /** **********************************     PUT请求          *****************************************/

    *queryPut({ payload, callback }, { put, call }) {
      const response = yield call(queryPut, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },

    *editPut({ payload, callback }, { put, call }) {
      const response = yield call(editPut, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },



    /** **************************************** DELETE请求    ***********************************/

    *removeDelete({ payload, callback }, { put, call }) {
      const response = yield call(removeDelete, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },

    *remove({ payload, callback }, { put, call }) {
      const response = yield call(remove, payload);
      yield put({
        type: 'save',
        payload: { loading: false },
      })
      if (callback) callback(response);
    },


    /*********考虑到多个页面共用common中的数据流时,会造成页面刷新前出现脏数据,此次加入清除数据的action,可以在componentWillMount中使用*******/
    *clearData({ }, { put }) {
      yield put({
        type: 'save',
        payload: { loading: true },
      });
      yield put({
        type: 'save',
        payload: {
          data: {
            list: [],
            pagination: {
              current: 1,
              pageSize: 10,
              total: 0
            },
            rows: [],
          },
          loading: false,
          listData: [],
        }
      });
    },

  },



  reducers: {
    save(state, action) {
      return {
        ...state,
        ...action.payload,
      }
    }
  }
}
